package com.flyqiu.form.store.mysql.mapper;


import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.flyqiu.common.mybaits.plus.FlyQiuQueryWrapper;
import com.flyqiu.form.common.FlyQiuFormConstant;
import com.flyqiu.form.model.SqlColumnModel;
import com.flyqiu.form.model.FlyQiuFormData;
import com.flyqiu.form.model.entity.FlyQiuTableConfig;
import com.flyqiu.form.model.vo.SqlColumnVo;
import org.apache.ibatis.annotations.*;

import java.util.List;
import java.util.Map;

@Mapper
@InterceptorIgnore(tenantLine = "true")
public interface FlyQiuFormMySqlStoreMapper {
    String TABLE_SELECT_SQL = """
            select  
             <foreach collection="column" item="item" separator=",">   
               ${item.prop}  
             </foreach>  
            from ${tableName} """;


    /**
     * 获取物理表列信息
     *
     * @param tableName
     * @return
     */
    @Select("""
             SELECT
            	column_name id,
            	column_name prop,
            	column_comment label,
            	data_type sql_data_type,
            	column_type sql_column_type,
            	IFNULL( CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION ) sql_data_length,
            	numeric_scale 'precision'
            FROM
            	information_schema.COLUMNS 
            WHERE
            	table_name = #{tableName} 
            	AND table_schema = (SELECT DATABASE()) 
            ORDER BY
            	ordinal_position
            """)
    List<SqlColumnModel> getTableColumns(@Param("tableName") String tableName);

    @Select(FlyQiuFormConstant.MBP_SCRIPT.START + TABLE_SELECT_SQL + " ${ew.customSqlSegment}" + FlyQiuFormConstant.MBP_SCRIPT.END)
    Page<Map<String, Object>> pageStorage(@Param("page") Page<Map<String, Object>> page,
                                          @Param("tableName") String tableName,
                                          @Param("column") List<SqlColumnModel> columns,
                                          @Param(Constants.WRAPPER) FlyQiuQueryWrapper query);


    @Select("""
            SELECT tables.TABLE_NAME      AS table_name,
            tables.ENGINE          AS engine_name,
            tables.TABLE_COMMENT   AS table_comment,
            tables.TABLE_COLLATION AS table_collation,
            tables.CREATE_TIME     AS create_time,
            tables.TABLE_SCHEMA    AS table_schema 
            FROM information_schema.TABLES 
            where table_schema = (select dataBase())
            AND tables.TABLE_NAME = #{tableName} limit 1
            """)
    Map<String, String> getTableByTableName(@Param("tableName") String tableName);

    @Select(FlyQiuFormConstant.MBP_SCRIPT.START + TABLE_SELECT_SQL + "  ${ew.customSqlSegment}" + FlyQiuFormConstant.MBP_SCRIPT.END)
    List<Map<String, Object>> storageList(@Param("tableName") String tableName,
                                          @Param("column") List<SqlColumnModel> column,
                                          @Param(Constants.WRAPPER) FlyQiuQueryWrapper query);


    @Select(FlyQiuFormConstant.MBP_SCRIPT.START + """
             ALTER TABLE ${tableName} 
             ADD COLUMN ${column.prop} ${column.sqlDataType}
             <if test="column.sqlDataLength!=null and column.sqlDataLength>0">(${column.sqlDataLength} <if test="column.precision!=null and column.precision>0">,${column.precision}</if> )</if>
             <if test="column.label!=null and column.label.length>0">COMMENT #{column.label}</if>;
            """
            + FlyQiuFormConstant.MBP_SCRIPT.END)
    void addColumn(@Param("tableName") String tableName, @Param("column") SqlColumnModel column);

    @Select(FlyQiuFormConstant.MBP_SCRIPT.START + """
            ALTER TABLE ${tableName} CHANGE ${column.oldProp} ${column.prop} ${column.sqlDataType}  
            <if test="column.sqlDataLength!=null and column.sqlDataLength>0">(${column.sqlDataLength} <if test="column.precision!=null and column.precision>0">,${column.precision}</if>)</if>   
            <if test="column.label!=null and column.label.length>0">COMMENT #{column.label}</if>;  
             """
            + FlyQiuFormConstant.MBP_SCRIPT.END)
    void updateColumn(@Param("tableName") String tableName, @Param("column") SqlColumnVo column);


    @Delete("ALTER TABLE ${tableName} DROP COLUMN ${column.prop}; ")
    void deleteColumn(@Param("tableName") String tableName, @Param("column") SqlColumnModel column);


    @Select(FlyQiuFormConstant.MBP_SCRIPT.START + """  
            insert into ${tableName}   
                  <foreach collection="columnData" item="data" separator="," close=")" open="(">   
                      ${data.prop}  
                 </foreach>   
                 values   
                  <foreach collection="columnData" item="data" separator="," close=")" open="(">  
                     #{data.dataValue}  
                 </foreach>""" + FlyQiuFormConstant.MBP_SCRIPT.END)
    void storageSave(@Param("tableName") String tableName, @Param("columnData") List<FlyQiuFormData> columnData);


    @Select(FlyQiuFormConstant.MBP_SCRIPT.START + """
            UPDATE ${tableName} SET  
                     <foreach collection="columnData" item="data" separator=",">  
                        ${data.prop}= #{data.dataValue}  
                     </foreach>  
                   ${ew.customSqlSegment}
            """ +
            FlyQiuFormConstant.MBP_SCRIPT.END)
    Long storageUpdate(@Param("tableName") String tableName,
                       @Param("columnData") List<FlyQiuFormData> columnData,
                       @Param(Constants.WRAPPER) FlyQiuQueryWrapper query);


    @Delete("DROP TABLE ${tableName}")
    void deleteTable(@Param("tableName") String tableName);


    @Delete("DELETE FROM ${tableName}")
    void clearData(@Param("tableName") String tableName);


    @Select(FlyQiuFormConstant.MBP_SCRIPT.START + """
             CREATE TABLE ${formConfig.tableName} ( 
             <foreach collection="columns" item="column" separator=","> 
              ${column.prop} ${column.sqlDataType}
               <if test="column.sqlDataLength!=null and column.sqlDataLength>0">
                 (${column.sqlDataLength}  <if test="column.precision!=null and column.precision>0">,#{column.precision}</if>  )
               </if> 
               <if test="column.label!=null and column.label.length>0">COMMENT #{column.label}</if> 
             </foreach>,
             PRIMARY KEY (id)) 
            <if test="formConfig.formName!=null and formConfig.formName.length>0">COMMENT=#{formConfig.formName}</if> 
            """
            + FlyQiuFormConstant.MBP_SCRIPT.END)
    Long createTable(@Param("formConfig") FlyQiuTableConfig formConfig, @Param("columns") List<SqlColumnModel> columns);


    @Update(" alter table ${formConfig.tableName} comment #{formConfig.formName} ")
    void updateTableComment(@Param("formConfig") FlyQiuTableConfig formConfig);


    @Select("  delete from ${tableName} ${ew.customSqlSegment} ")
    Long storageRemove(@Param("tableName") String tableName, @Param(Constants.WRAPPER) FlyQiuQueryWrapper queryWrapper);


    @Select(" select count(*)  from ${tableName} ${ew.customSqlSegment} ")
    Long storageCount(@Param("tableName") String tableName, @Param(Constants.WRAPPER) FlyQiuQueryWrapper queryWrapper);
}
